package io.hellsinger.vortex.ui.screen.storage.create

import io.hellsinger.viewmodel.BitViewModel
import io.hellsinger.viewmodel.intent
import io.hellsinger.vortex.Dispatchers
import io.hellsinger.vortex.bit.Bits.Companion.addFlag

class StorageCreateItemViewModel(
    private val dispatchers: Dispatchers,
) : BitViewModel<UiState>("Create Item scope") {
    private val state = MutableUiState()

    fun data(): UiState = state

    override fun getUiState(): UiState = state

    fun updateName(name: String) =
        intent {
            state.name = name
            validateAttribute {
                if (name.isEmpty()) REASON_PART_IS_EMPTY
                if (name.contains('/')) REASON_INVALID_SYMBOL
                if (name.contains('\u0000')) REASON_INVALID_SYMBOL
                PART_IS_OKAY
            }
        }

    fun updatePath(path: String) =
        intent {
            state.path = path
            validateAttribute {
                if (path.isEmpty()) REASON_PART_IS_EMPTY
                if (path[0] != '/') REASON_PATH_MUST_STARTS_FROM_SLASH
                PART_IS_OKAY
            }
        }

    fun updateType(type: String) =
        intent {
            state.type = type
            validateAttribute {
                PART_IS_OKAY
            }
        }

    fun updatePermission(permission: String) =
        intent {
            state.permission = permission
            validateAttribute {
                PART_IS_OKAY
            }
        }

    private suspend inline fun validateAttribute(validator: () -> Int) {
        val result = validator()
        if (result != PART_IS_OKAY) update(UPDATE_INVALID_FIELD_NAME addFlag result)
    }

    companion object {
        const val PART_IS_OKAY = 0
        const val REASON_PART_IS_EMPTY = 1 shl 0
        const val REASON_INVALID_SYMBOL = 1 shl 1
        const val REASON_PATH_MUST_STARTS_FROM_SLASH = 1 shl 2

        const val UPDATE_INVALID_FIELD_NAME = 1 shl 6
        const val UPDATE_INVALID_FIELD_PATH = 1 shl 7
        const val UPDATE_INVALID_FIELD_TYPE = 1 shl 8
        const val UPDATE_INVALID_FIELD_PERMISSION = 1 shl 9

        const val UPDATE_FIELD_NAME = 1 shl 10
        const val UPDATE_FIELD_PATH = 1 shl 11
        const val UPDATE_FIELD_TYPE = 1 shl 12
        const val UPDATE_FIELD_PERMISSION = 1 shl 13
    }
}
